home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / sos3-2.lha / src / agg / Array_scp.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  22KB  |  613 lines

  1. #line 1 "/fzi/prost/stone/SOS3-2/src/agg/Array.c"
  2. /* --------------------------------------------------------------------------
  3.  * Copyright 1992 by Forschungszentrum Informatik (FZI)
  4.  *
  5.  * You can use and distribute this software under the terms of the licence
  6.  * you should have received along with this program.
  7.  * If not or if you want additional information, write to
  8.  * Forschungszentrum Informatik, "STONE", Haid-und-Neu-Strasse 10-14,
  9.  * D-7500 Karlsruhe 1, Germany.
  10.  * --------------------------------------------------------------------------
  11.  */
  12. // **************************************************************************
  13. // Module Array                     30/08/89           Bernhard Schiefer (bs)
  14. //                                                              26/06/90 (bs)
  15. // **************************************************************************
  16. // implements methods of classes: Array
  17. // **************************************************************************
  18.  
  19. #include "sys.h"
  20. #include "knl_err.h"
  21. #include "agg_err.h"
  22. #include "trc_agg.h"
  23.  
  24. #include "agg_sos.h"
  25.  
  26. // **************************************************************************
  27. sos_Int _sos_Object_Array::element_size (sos_Typed_id &_tpid)
  28. // **************************************************************************
  29. {
  30.    return SOS_TYPED_ID_SIZE;    // as long as only references are stored!
  31.                                 // otherwise get the size of the Array's
  32.                 // element type from the schema
  33. } // ** element_size **
  34.  
  35. // **************************************************************************
  36. void _sos_Object_Array::local_initialize (sos_Object_Array arr)
  37. // **************************************************************************
  38. {
  39.    T_PROC ("sos_Object_Array::local_initialize");
  40.    TT (agg_H, T_ENTER);
  41.  
  42.    Index c = arr.get_top_index() - arr.get_bottom_index() + 1;
  43.  
  44.    if (c<=0)
  45.       arr.set_address (0);
  46.    else
  47.       arr.set_address (arr.container().allocate(c*arr.element_size()));
  48.  
  49.    TT (agg_H, T_LEAVE);
  50. } // ** local_initialize **
  51.  
  52. // **************************************************************************
  53. void _sos_Object_Array::local_finalize (sos_Object_Array arr)
  54. // **************************************************************************
  55. {
  56.    T_PROC ("sos_Object_Array::local_finalize");
  57.    TT (agg_H, T_ENTER);
  58.  
  59.    sos_Int length = arr.card()*arr.element_size();
  60.  
  61.    if (length > 0)
  62.       arr.container().deallocate (arr.get_address(), length);
  63.  
  64.    TT (agg_H, T_LEAVE);
  65. } // ** local_finalize **
  66.  
  67. // **************************************************************************
  68. Index _sos_Object_Array::get_bottom (sos_Typed_id &_tpid)
  69. // **************************************************************************
  70. {
  71.    T_PROC ("sos_Object_Array::get_bottom");
  72.    TT (agg_H, T_ENTER);
  73.  
  74.    Index b = sos_Object_Array::make(_tpid,this).get_bottom_index();
  75.  
  76.    TT (agg_H, T_LEAVE; TI (b));
  77.    return b;
  78. } // ** get_bottom **
  79.  
  80. // **************************************************************************
  81. Index _sos_Object_Array::get_top (sos_Typed_id &_tpid)
  82. // **************************************************************************
  83. {
  84.    T_PROC ("sos_Object_Array::get_bottom");
  85.    TT (agg_H, T_ENTER);
  86.  
  87.    Index t = sos_Object_Array::make(_tpid,this).get_top_index();
  88.  
  89.    TT (agg_H, T_LEAVE; TI (t));
  90.    return t;
  91. } // ** get_top **
  92.  
  93. // **************************************************************************
  94. sos_Object _sos_Object_Array::get_nth (sos_Typed_id &_tpid,Index pos)
  95. // **************************************************************************
  96. {
  97.    T_PROC ("sos_Object_Array::get_nth");
  98.    TT (agg_H, T_ENTER; TI (pos));
  99.  
  100.    if ((pos < sos_Object_Array::make(_tpid,this).get_bottom()) OR (pos > sos_Object_Array::make(_tpid,this).get_top()))
  101.    {  err_raise (err_USE, err_AGG_ARRAY_POS_INVALID, "sos_Object_Array::get_nth", FALSE);
  102.       TT (agg_H, T_LEAVE );
  103.       return (NO_OBJECT);
  104.    }
  105.  
  106.    sos_Offset act_pos = sos_Object_Array::make(_tpid,this).get_address() +
  107.             ((pos - sos_Object_Array::make(_tpid,this).get_bottom()) * sos_Object_Array::make(_tpid,this).element_size());
  108.  
  109.    sos_Typed_id tpid;
  110.    sos_Char c[SOS_TYPED_ID_SIZE];
  111.    sos_Object_Array::make(_tpid,this).container().read (act_pos, SOS_TYPED_ID_SIZE, c);
  112.    bcopy_to_sos_Typed_id (&tpid, c);
  113.  
  114.    sos_Object o = sos_Object::make (tpid);
  115.  
  116.    TT (agg_H, T_LEAVE; TI(act_pos));
  117.    return o;
  118. } // ** get_nth **
  119.  
  120. // **************************************************************************
  121. void _sos_Object_Array::set_nth (sos_Typed_id &_tpid,Index pos, sos_Object o)
  122. // **************************************************************************
  123. {
  124.    T_PROC ("sos_Object_Array::set_nth");
  125.    TT (agg_H, T_ENTER; TI (pos));
  126.  
  127.    if ((pos < sos_Object_Array::make(_tpid,this).get_bottom()) OR (pos > sos_Object_Array::make(_tpid,this).get_top()))
  128.    {  err_raise (err_USE, err_AGG_ARRAY_POS_INVALID, "sos_Object_Array::set_nth", FALSE);
  129.       TT (agg_H, T_LEAVE );
  130.       return;
  131.    }
  132.  
  133.    sos_Offset act_pos = sos_Object_Array::make(_tpid,this).get_address() +
  134.             ((pos - sos_Object_Array::make(_tpid,this).get_bottom()) * sos_Object_Array::make(_tpid,this).element_size());
  135.  
  136.    sos_Typed_id tpid = o.typed_id();
  137.    sos_Char c[SOS_TYPED_ID_SIZE];
  138.    bcopy_from_sos_Typed_id (&tpid, c);
  139.    sos_Object_Array::make(_tpid,this).container().write (act_pos, SOS_TYPED_ID_SIZE, c);
  140.  
  141.    TT (agg_H, T_LEAVE; TI(act_pos));
  142. } // ** set_nth **
  143.  
  144. // **************************************************************************
  145. void _sos_Object_Array::shift (sos_Typed_id &_tpid,Index start, sos_Int number)
  146. // **************************************************************************
  147. {
  148.    // Inclusively the specified 'start' element, all elements of the Array
  149.    // will be shifted 'number' elements.
  150.    // The direction depends on the sign: + means right, - means left.
  151.    // 'number' elements left from 'start' will be overwritten!
  152.    // The value of the last 'number' elements in the Array is undefined!
  153.  
  154.    T_PROC ("sos_Object_Array::shift");
  155.    TT (agg_H, T_ENTER; TI (start); TI (number));
  156.  
  157.    Index b = sos_Object_Array::make(_tpid,this).get_bottom();
  158.    Index t = sos_Object_Array::make(_tpid,this).get_top();
  159.  
  160.    if ((start < b) OR (start > sos_Object_Array::make(_tpid,this).get_top()))
  161.    {  err_raise (err_USE, err_AGG_ARRAY_POS_INVALID, "sos_Object_Array::shift()", FALSE);
  162.       TT (agg_H, T_LEAVE );
  163.       return;
  164.    }
  165.  
  166.    Index goal = start + number;
  167.  
  168.    if ((goal < b) OR (goal > t))
  169.    {  err_raise (err_USE, err_AGG_ARRAY_POS_INVALID, "sos_Object_Array::shift()", FALSE);
  170.       TT (agg_H, T_LEAVE );
  171.       return;
  172.    }
  173.  
  174.    sos_Offset a = sos_Object_Array::make(_tpid,this).get_address();
  175.    sos_Int size = sos_Object_Array::make(_tpid,this).element_size();
  176.  
  177.    sos_Offset from_pos = a + sos_Offset ((start - b) * size);
  178.    sos_Offset to_pos   = a + sos_Offset ((goal - b) * size);
  179.    sos_Int slice_length;
  180.    if (goal > start)
  181.       slice_length = t - goal + 1;
  182.    else
  183.       slice_length = t - start + 1;
  184.  
  185.    sos_Object_Array::make(_tpid,this).container().copy (from_pos, slice_length * size,
  186.                sos_Object_Array::make(_tpid,this).container(), to_pos);
  187.               // copy takes care of the correct moving of Bytes in a container!
  188.  
  189.    TT (agg_H, T_LEAVE);
  190. } // ** shift **
  191.  
  192. // **************************************************************************
  193. void _sos_Object_Array::rotate (sos_Typed_id &_tpid,sos_Int number)
  194. // **************************************************************************
  195. {
  196.    T_PROC ("sos_Object_Array::rotate");
  197.    TT (agg_H, T_ENTER; TI (number));
  198.  
  199.    sos_Int crd = sos_Object_Array::make(_tpid,this).card();
  200.    if (crd == 0)
  201.    {  TT (agg_H, T_LEAVE);
  202.       return;
  203.    }
  204.  
  205.    Index  bottom  = sos_Object_Array::make(_tpid,this).get_bottom(); 
  206.    Index  top     = sos_Object_Array::make(_tpid,this).get_top(); 
  207.    sos_Object o;
  208.    sos_Int i;
  209.                                            // Very inefficient but simple
  210.                                            // implementation!
  211.    if (number > 0)  // rotate right
  212.       for (i = number MOD crd; i > 0; i--)
  213.       {  o = sos_Object_Array::make(_tpid,this).get_nth (top);
  214.          sos_Object_Array::make(_tpid,this).shift (bottom, 1);
  215.          sos_Object_Array::make(_tpid,this).set_nth (bottom, o);
  216.       } // for
  217.  
  218.    else
  219.       for (i = (-number) MOD crd; i > 0; i--)
  220.       {  o = sos_Object_Array::make(_tpid,this).get_nth (bottom);
  221.          sos_Object_Array::make(_tpid,this).shift (bottom+1, -1);
  222.          sos_Object_Array::make(_tpid,this).set_nth (top, o);
  223.       } // for
  224.  
  225.    TT (agg_H, T_LEAVE);
  226. } // ** rotate **
  227.  
  228. // **************************************************************************
  229. sos_Object _sos_Object_Array::__index (sos_Typed_id &_tpid,Index i)
  230. // **************************************************************************
  231. {
  232.    T_PROC ("sos_Object_Array::operator[]");
  233.    TT (agg_H, T_ENTER);
  234.  
  235.    sos_Object o = sos_Object_Array::make(_tpid,this).get_nth (i);
  236.  
  237.    TT (agg_H, T_LEAVE);
  238.    return o;
  239. } // ** operator[] **
  240.  
  241. // **************************************************************************
  242. Index _sos_Object_Array::current_pos (sos_Typed_id &_tpid,sos_Cursor c)
  243. // **************************************************************************
  244. {
  245.    T_PROC ("sos_Object_Array::current_pos");
  246.    TT (agg_H, T_ENTER);
  247.  
  248.    if (NOT sos_Object_Array::make(_tpid,this).is_valid (c))
  249.    {  err_raise (err_USE, err_AGG_WRONG_CURSOR, "sos_Object_Array::current_pos()", FALSE);
  250.       TT (agg_H, T_LEAVE );
  251.       return (0);
  252.    }
  253.  
  254.    Index pos = sos_Array_node::make (c.get_current()).get_index();
  255.  
  256.    TT (agg_H, T_LEAVE; TI (pos));
  257.    return pos;
  258. } // ** current_pos **
  259.  
  260. // **************************************************************************
  261. sos_Bool _sos_Object_Array::move_cursor (sos_Typed_id &_tpid,sos_Cursor c, Index pos)
  262. // **************************************************************************
  263. {
  264.    T_PROC ("sos_Object_Array::move_cursor");
  265.    TT (agg_H, T_ENTER; TI (pos));
  266.  
  267.    if (NOT c.defined_for (sos_Object_Array::make(_tpid,this)))
  268.    {  err_raise (err_USE, err_AGG_WRONG_CURSOR, "sos_Object_Array::move_cursor()", FALSE);
  269.       TT (agg_H, T_LEAVE );
  270.       return (FALSE);
  271.    }
  272.  
  273.    if ((pos < sos_Object_Array::make(_tpid,this).get_bottom()) OR (pos > sos_Object_Array::make(_tpid,this).get_top()))
  274.    {  err_raise (err_USE, err_AGG_ARRAY_POS_INVALID, "sos_Object_Array::move_cursor()", FALSE);
  275.       TT (agg_H, T_LEAVE );
  276.       return (FALSE);
  277.    }
  278.  
  279.    sos_Array_node::make (c.get_current()).set_index (pos);
  280.  
  281.    TT (agg_H, T_LEAVE);
  282.    return TRUE;          // invalid positions 'pos' cause an error!
  283. } // ** move_cursor **
  284.  
  285. // **************************************************************************
  286. sos_Int _sos_Object_Array::size(sos_Typed_id &_tpid)
  287. // **************************************************************************
  288. {  T_PROC ("sos_Object_Array::size");
  289.    TT (agg_H, T_ENTER);
  290.  
  291.    sos_Int sz = sos_Object_Array::make(_tpid,this).container().rounded (sos_Object_Array::make(_tpid,this).card() * SOS_TYPED_ID_SIZE) +
  292.         _sos_Object::size(_tpid);
  293.  
  294.    TT (agg_H, T_LEAVE);
  295.    return sz;
  296. } // * size **
  297.  
  298. // **************************************************************************
  299. void _sos_Object_Array::local_assign (sos_Object_Array x, sos_Object o)
  300. // **************************************************************************
  301. {
  302.    // This function copies the contents of its argument onto
  303.    // the contents of (x).
  304.    // If (x) is larger than the argument, then only the first
  305.    // array_obj.card bytes are overwritten.
  306.    // If (x) is smaller than the argument, then only the first
  307.    // x.card bytes are copied.
  308.  
  309.    T_PROC ("sos_Object_Array::local_assign");
  310.    TT (agg_H, T_ENTER);
  311.  
  312.    sos_Object_Array y = sos_Object_Array::make (o);
  313.    Index data_size;
  314.    Index y_crd = y.card();
  315.    Index x_crd = x.card();
  316.    sos_Int size = x.element_size();
  317.  
  318.    if (x_crd < y_crd)
  319.       data_size = x_crd * size;
  320.    else
  321.       data_size = y_crd * size;
  322.  
  323.    Index data_begin_of_x = x.get_address();
  324.    Index data_begin_of_y = y.get_address();
  325.  
  326.    y.container().copy (data_begin_of_y, data_size,
  327.                        x.container(), data_begin_of_x);
  328.  
  329.    TT (agg_H, T_LEAVE; TI(data_begin_of_y); TI(data_size);
  330.                        TI(data_begin_of_x));
  331. } // ** local_assign **
  332.  
  333. // **************************************************************************
  334. sos_Bool _sos_Object_Array::local_equal (sos_Object_Array x,
  335.                         sos_Object     o,
  336.                         sos_Eq_kind     eq_kind)
  337. // **************************************************************************
  338. {
  339.    T_PROC ("sos_Object_Array::local_equal");
  340.    TT (agg_H, T_ENTER );
  341.  
  342.    sos_Bool result;
  343.  
  344.    if ((eq_kind EQ EQ_STRONG AND NOT o.has_type(x.type())) OR
  345.        (eq_kind EQ EQ_WEAK   AND NOT o.isa     (x.type())))
  346.       result = FALSE;
  347.    else
  348.    {  sos_Int c = x.card();
  349.       sos_Object_Array y = sos_Object_Array::make (o);
  350.       if (c != y.card())
  351.      result = FALSE;
  352.       else
  353.       {  result = TRUE;
  354.      sos_Bool based_on_equal = x.get_based_on_equal();
  355.      Index b1 = x.get_bottom();
  356.      Index b2 = y.get_bottom();
  357.      sos_Object o1, o2;
  358.      for ( ; c>0 AND result; b1++, b2++, c--)
  359.      {  o1 = x.get_nth (b1);
  360.         o2 = y.get_nth (b2);
  361.         result = agg_same_entity (o1, o2, based_on_equal, eq_kind);
  362.      }
  363.       }
  364.    }
  365.  
  366.    TT (agg_H, T_LEAVE);
  367.    return result;
  368. } // ** local_equal **
  369.  
  370. // **************************************************************************
  371. sos_Int _sos_Object_Array::local_hash_value (sos_Object_Array x)
  372. // **************************************************************************
  373. {
  374.    T_PROC ("sos_Object_Array::local_hash_value");
  375.    TT (agg_H, T_ENTER );
  376.  
  377.    sos_Int result;
  378.  
  379.    if (x.is_empty())
  380.       result = 0;
  381.    else
  382.       result = x.get_nth (x.get_bottom()).hash_value() ^
  383.            x.get_nth (x.get_top()).hash_value();
  384.  
  385.    TT (agg_H, T_LEAVE);
  386.    return result;
  387. } // ** local_hash_value **
  388.  
  389. // **************************************************************************
  390. sos_Object _sos_Object_Array::get (sos_Typed_id &_tpid,sos_Cursor c)
  391. // **************************************************************************
  392. {
  393.    T_PROC ("sos_Object_Array::get");
  394.    TT (agg_H, T_ENTER);
  395.  
  396.    if (NOT sos_Object_Array::make(_tpid,this).is_valid (c))
  397.    {  err_raise (err_USE, err_AGG_CURSOR_POS_INVALID, "sos_Object_Array::get()", FALSE);
  398.       TT (agg_H, T_LEAVE);
  399.       return (NO_OBJECT);
  400.    }
  401.  
  402.    sos_Object o = sos_Object_Array::make(_tpid,this).get_nth (sos_Object_Array::make(_tpid,this).current_pos (c));
  403.  
  404.    TT (agg_H, T_LEAVE);
  405.    return (o);
  406. } // ** get **
  407.  
  408. // **************************************************************************
  409. void _sos_Object_Array::set (sos_Typed_id &_tpid,sos_Cursor c, sos_Object o)
  410. // **************************************************************************
  411. {
  412.    T_PROC ("sos_Object_Array::set");
  413.    TT (agg_H, T_ENTER);
  414.  
  415.    if (NOT sos_Object_Array::make(_tpid,this).is_valid (c))
  416.    {  err_raise (err_USE, err_AGG_CURSOR_POS_INVALID, "sos_Object_Array::set()", FALSE);
  417.       TT (agg_H, T_LEAVE);
  418.       return;
  419.    }
  420.  
  421.    sos_Object_Array::make(_tpid,this).set_nth (sos_Object_Array::make(_tpid,this).current_pos (c), o);
  422.  
  423.    TT (agg_H, T_LEAVE);
  424. } // ** set **
  425.  
  426. // **************************************************************************
  427. void _sos_Object_Array::remove_at (sos_Typed_id &_tpid,sos_Cursor c)
  428. // **************************************************************************
  429. {
  430.    // The current element, identified by the sos_Cursor c will be
  431.    // removed from the Array. This means in this case, that
  432.    // it will be replaced by NO_OBJECT. The operation returns the removed
  433.    // object. After this operation, get(c) will return the next
  434.    // element in the aggregate
  435.  
  436.    T_PROC ("sos_Object_Array::remove_at");
  437.    TT (agg_H, T_ENTER);
  438.  
  439.    if (NOT sos_Object_Array::make(_tpid,this).is_valid (c))
  440.    {  err_raise (err_USE, err_AGG_CURSOR_POS_INVALID, "sos_Object_Array::remove_at()", FALSE);
  441.       TT (agg_H, T_LEAVE);
  442.    }
  443.  
  444.    sos_Object_Array::make(_tpid,this).set (c, NO_OBJECT);
  445.    sos_Object_Array::make(_tpid,this).to_succ (c);
  446.  
  447.    TT (agg_H, T_LEAVE);
  448. } // ** remove_at **
  449.  
  450. // **************************************************************************
  451. sos_Int _sos_Object_Array::card (sos_Typed_id &_tpid)
  452. // **************************************************************************
  453. {
  454.    T_PROC ("sos_Object_Array::card");
  455.    TT (agg_H, T_ENTER);
  456.  
  457.    sos_Int crd = sos_Object_Array::make(_tpid,this).get_top_index() - sos_Object_Array::make(_tpid,this).get_bottom_index() + 1;
  458.    if (crd<0) crd=0;
  459.  
  460.    TT (agg_H, T_LEAVE);
  461.    return crd;
  462. } // ** card **
  463.  
  464. // **************************************************************************
  465. sos_Cursor _sos_Object_Array::open_cursor (sos_Typed_id &_tpid,sos_Container ct)
  466. // **************************************************************************
  467. {
  468.    // creates a new cursor-object and positions it 
  469.    // to the first element
  470.  
  471.    T_PROC ("sos_Object_Array::open_cursor");
  472.    TT (agg_H, T_ENTER);
  473.  
  474.    sos_Cursor new_c = sos_Cursor::create (ct, sos_Object_Array::make(_tpid,this));
  475.    sos_Array_node new_an = sos_Array_node::create (ct);
  476.    new_an.set_index (sos_Object_Array::make(_tpid,this).get_bottom());
  477.    new_c.set_current (new_an);
  478.    sos_Object_Array::make(_tpid,this).to_first (new_c);
  479.  
  480.    TT (agg_H, T_LEAVE);
  481.    return new_c;
  482. } // ** open_cursor **
  483.  
  484. // **************************************************************************
  485. void _sos_Object_Array::close_cursor (sos_Typed_id &_tpid,sos_Cursor c)
  486. // **************************************************************************
  487. {
  488.    // The result of any operation using sos_Cursor c
  489.    // is undefined after this operation.
  490.  
  491.    T_PROC ("sos_Object_Array::close_cursor");
  492.    TT (agg_H, T_ENTER);
  493.  
  494.    if (NOT c.defined_for (sos_Object_Array::make(_tpid,this)))
  495.    {  err_raise (err_USE, err_AGG_WRONG_CURSOR, NULL, FALSE);
  496.       TT (agg_H, T_LEAVE);
  497.       return;
  498.    }
  499.  
  500.    c.get_current().destroy();
  501.    c.destroy();
  502.  
  503.    TT (agg_H, T_LEAVE);
  504. } // ** close_cursor **
  505.  
  506. // **************************************************************************
  507. sos_Cursor _sos_Object_Array::duplicate (sos_Typed_id &_tpid,sos_Cursor c)
  508. // **************************************************************************
  509. {
  510.    // creates a new cursor-object for the Aggregate and
  511.    // positions it to the same element as c
  512.  
  513.    T_PROC ("sos_Object_Array::duplicate");
  514.    TT (agg_H, T_ENTER);
  515.  
  516.    if (NOT c.defined_for(sos_Object_Array::make(_tpid,this)))
  517.    {  err_raise (err_USE, err_AGG_WRONG_CURSOR, NULL, FALSE);
  518.       TT (agg_H, T_LEAVE);
  519.       return (sos_Cursor::make (NO_OBJECT));
  520.    }
  521.  
  522.    sos_Cursor new_c = sos_Cursor::create (c.container(), sos_Object_Array::make(_tpid,this));
  523.    sos_Array_node new_an = sos_Array_node::create (c.container());
  524.    new_an.set_index (sos_Object_Array::make(_tpid,this).get_bottom());
  525.    new_c.set_current (new_an);
  526.  
  527.    TT (agg_H, T_LEAVE);
  528.    return new_c;
  529. } // ** duplicate **
  530.  
  531. // **************************************************************************
  532. sos_Bool _sos_Object_Array::is_valid (sos_Typed_id &_tpid,sos_Cursor c)
  533. // **************************************************************************
  534. {
  535.    T_PROC ("sos_Object_Array::is_valid");
  536.    TT (agg_H, T_ENTER);
  537.  
  538.    Index    i     = sos_Array_node::make (c.get_current()).get_index();
  539.    sos_Bool valid = (sos_Bool) (i <= sos_Object_Array::make(_tpid,this).get_top() AND i >= sos_Object_Array::make(_tpid,this).get_bottom());
  540.  
  541.    TT (agg_H, T_LEAVE; TB(valid));
  542.    return valid;
  543. } // ** is_valid **
  544.  
  545. // **************************************************************************
  546. sos_Bool _sos_Object_Array::to_first (sos_Typed_id &_tpid,sos_Cursor c)
  547. // **************************************************************************
  548. {
  549.    T_PROC ("sos_Object_Array::to_first");
  550.    TT (agg_H, T_ENTER);
  551.  
  552.    Index new_i = sos_Object_Array::make(_tpid,this).get_bottom();
  553.  
  554.    sos_Bool valid = (sos_Bool) (new_i <= sos_Object_Array::make(_tpid,this).get_top());
  555.    sos_Array_node::make (c.get_current()).set_index (new_i);
  556.  
  557.    TT (agg_H, T_LEAVE; TB(valid));
  558.    return (valid);
  559. } // ** to_first **
  560.  
  561. // **************************************************************************
  562. sos_Bool _sos_Object_Array::to_last (sos_Typed_id &_tpid,sos_Cursor c)
  563. // **************************************************************************
  564. {
  565.    T_PROC ("sos_Object_Array::to_last");
  566.    TT (agg_H, T_ENTER);
  567.  
  568.    Index new_i = sos_Object_Array::make(_tpid,this).get_top();
  569.  
  570.    sos_Bool valid = (sos_Bool) (new_i <= sos_Object_Array::make(_tpid,this).get_bottom());
  571.    sos_Array_node::make (c.get_current()).set_index (new_i);
  572.  
  573.    TT (agg_H, T_LEAVE; TB(valid));
  574.    return (valid);
  575. } // ** to_last **
  576.  
  577. // **************************************************************************
  578. sos_Bool _sos_Object_Array::to_succ (sos_Typed_id &_tpid,sos_Cursor c, sos_Int i)
  579. // **************************************************************************
  580. {
  581.    T_PROC ("sos_Object_Array::to_succ");
  582.    TT (agg_H, T_ENTER; TI (i));
  583.  
  584.    sos_Array_node an = sos_Array_node::make (c.get_current());
  585.    Index new_i = an.get_index() + i;
  586.  
  587.    sos_Bool valid = (sos_Bool) (new_i <= sos_Object_Array::make(_tpid,this).get_top());
  588.    an.set_index (new_i);
  589.  
  590.    TT (agg_H, T_LEAVE; TB(valid));
  591.    return (valid);
  592. } // ** to_succ **
  593.  
  594. // **************************************************************************
  595. sos_Bool _sos_Object_Array::to_pred (sos_Typed_id &_tpid,sos_Cursor c, Index i)
  596. // **************************************************************************
  597. {
  598.    // Move the sos_Cursor to the previous i-th element
  599.    // The function returns FALSE if no such element exists.
  600.  
  601.    T_PROC ("sos_Object_Array::to_pred");
  602.    TT (agg_H, T_ENTER; TI (i));
  603.  
  604.    sos_Array_node an = sos_Array_node::make (c.get_current());
  605.    Index new_i = an.get_index() - i;
  606.  
  607.    sos_Bool valid = (sos_Bool) (new_i <= sos_Object_Array::make(_tpid,this).get_bottom());
  608.    an.set_index (new_i);
  609.  
  610.    TT (agg_H, T_LEAVE; TB(valid));
  611.    return (valid);
  612. } // ** to_pred **
  613.